package com.fhx.core.utils

import android.util.Log
import com.fhx.core.AppContext
import okhttp3.*
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream

class DownloadUtil private constructor() {
    private val okHttpClient: OkHttpClient
    companion object {
        private var downloadUtil: DownloadUtil? = null
        fun get(): DownloadUtil? {
            if (downloadUtil == null) {
                downloadUtil = DownloadUtil()
            }
            return downloadUtil
        }
    }

    init {
        okHttpClient = OkHttpClient()
    }
    /**
     * @param url 下载连接
     * @param saveDir 储存下载文件的SDCard目录
     * @param listener 下载监听
     */
    fun download(
        url: String?,
        saveDir: String,
        fileName: String,
        listener: OnDownloadListener
    ) {
        // 需要token的时候可以这样做
        // SharedPreferences sp=MyApp.getAppContext().getSharedPreferences("loginInfo", MODE_PRIVATE);
        // Request request = new Request.Builder().header("token",sp.getString("token" , "")).url(url).build();
        val request = Request.Builder().url(url!!).build()
        okHttpClient.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                // 下载失败
                e.printStackTrace()
                listener.onDownloadFailed()
            }

            @Throws(IOException::class)
            override fun onResponse(
                call: Call,
                response: Response
            ) {
                var inputStream: InputStream? = null
                val buf = ByteArray(2048)
                var len = 0
                var fos: FileOutputStream? = null
                // 储存下载文件的目录
                val savePath = isExistDir(saveDir)
                LogUtils.debug("存储下载目录：$savePath")
                try {
                    inputStream = response.body!!.byteStream()
                    val total = response.body!!.contentLength()
                    val file = File(savePath, getNameFromUrl(fileName))
                    LogUtils.debug("最终路径：${file.absolutePath}")
                    if(file.exists()){
                        file.delete()
                    }
                    fos = FileOutputStream(file)
                    var sum: Long = 0
                    while (inputStream.read(buf).also { len = it } != -1) {
                        fos.write(buf, 0, len)
                        sum += len.toLong()
                        val progress = (sum * 1.0f / total * 100).toInt()
                        // 下载中
                        listener.onDownloading(progress)
                    }
                    fos.flush()
                    // 下载完成
                    listener.onDownloadSuccess(file.absolutePath)
                } catch (e: Exception) {
                    listener.onDownloadFailed()
                    e.printStackTrace()
                } finally {
                    try {
                        inputStream?.close()
                    } catch (e: IOException) {
                    }
                    try {
                        fos?.close()
                    } catch (e: IOException) {
                    }
                }
            }
        })
    }

    /**
     * @param saveDir
     * @return
     * @throws IOException
     * 判断下载目录是否存在
     */
    @Throws(IOException::class)
    private fun isExistDir(saveDir: String): String {
        // 下载位置
        val downloadFile = File(AppContext.instance.getExternalFilesDir(null)!!.absolutePath, saveDir)
        if (!downloadFile.mkdirs()) {
            downloadFile.createNewFile()
        }
        return downloadFile.absolutePath
    }
    fun getDownLoadFile(saveDir: String,fileName:String):File{
        val savePath = isExistDir(saveDir)
        return File(savePath, getNameFromUrl(fileName))
    }
    /**
     * @param url
     * @return
     * 传入文件名
     */
    fun getNameFromUrl(url: String): String {
        return url
    }

    interface OnDownloadListener {
        /**
         * 下载成功
         */
        fun onDownloadSuccess(path:String)

        /**
         * @param progress
         * 下载进度
         */
        fun onDownloading(progress: Int)

        /**
         * 下载失败
         */
        fun onDownloadFailed()
    }

}